//
//  GCDTableViewController.h
//  objective_c_language
//
//  Created by 王玉龙 on 2018/6/5.
//  Copyright © 2018年 longlong. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface GCDTableViewController : UITableViewController

@end

/*
 提出一些问题: https://bestswifter.com/deep-gcd/
 1、dispatch_async 函数如何实现，分发到主队列和全局队列有什么区别，一定会新建线程执行任务么？
 2、dispatch_sync 函数如何实现，为什么说 GCD 死锁是队列导致的而不是线程，死锁不是操作系统的概念么？
 3、信号量是如何实现的，有哪些使用场景？
 4、dispatch_group 的等待与通知、dispatch_once 如何实现？
 5、dispatch_source 用来做定时器如何实现，有什么优点和用途？
 6、dispatch_suspend 和 dispatch_resume 如何实现，队列的的暂停和计时器的暂停有区别么？
 */

/* 队列：执行任务的等待队列，即用来存放任务的队列。
 队列是一种特殊的线性表，采用 FIFO（先进先出）的原则，即新任务总是被插入到队列的末尾，而读取任务的时候总是从队列的头部开始读取。每读取一个任务，则从队列中释放一个任务
 它衍生出来的就是下面的它的分类：并发和串行队列，一条线程上可以有多个队列。
 两者都符合 FIFO（先进先出）的原则。两者的主要区别是：执行顺序不同，以及开启线程数不同。
 
 1、并发队列（Concurrent Dispatch Queue）：可以让多个任务并发（同时）执行（可以开启多个线程，并且同时执行任务）。
 并发队列 + 同步任务： 同步任务只能在当前线程中执行任务，不具备开启新线程的能力。所以 并发队列 + 同步任务 只会在一条线程里面同步执行这些任务，又由于同步任务在当前线程中执行，这个时候就需要一个任务执行完毕后，再执行下一个任务。
 并发队列 + 异步任务：对应着开启异步线程执行要执行的任务，就会同一时间又许多的任务被执行。
 
 注意：并发队列 的并发功能只有在异步（dispatch_async）函数下才有效
 
 
 2、串行队列（Serial Dispatch Queue）：每次只有一个任务被执行。让任务一个接着一个地执行。（只开启一个线程，一个任务执行完毕后，再执行下一个任务）
 
 
 3、主队列：对于串行队列，GCD 提供了的一种特殊的串行队列：主队列（Main Dispatch Queue）。
 所有放在主队列中的任务，都会放到主线程中执行。
 */

/* 任务：就是执行操作的意思，换句话说就是你在线程中执行的那段代码。在 GCD 中是放在 block 中的。执行任务有两种方式：同步执行（sync）和异步执行（async）。两者的主要区别是：是否等待队列的任务执行结束，以及是否具备开启新线程的能力。
 
 同步任务：同步添加任务到指定的队列中，在添加的任务执行结束之前，会阻塞当前的线程一直等待，直到队列里面的任务完成之后再继续执行。
 只能在当前线程中执行任务，不具备开启新线程的能力。
 
 异步任务：异步添加任务到指定的队列中，它不会阻塞当前的线程，可以继续执行任务。
 可以在新的线程中执行任务，具备开启新线程的能力。
 注意：异步任务虽然具有开启新线程的能力，但是并不一定开启新线程。这跟任务所指定的队列类型有关。
 */

/*
 队列 + 任务
 
 区别         并发队列        串行队列                 主队列
 
 同步任务   没有开辟新线程，    没有开辟新线程，        没有开辟新线程，
 串行执行这个任务    串行执行这个任务        串行执行这个任务
 
 异步任务   开辟新线程，         开辟新线程（1条），   没有开辟新线程，
 并发执行这个任务      串行执行这个任务      串行执行这个任务
 
 */

/*
 构建队列
 dispatch_queue_t dispatch_queue_create(const char *_Nullable label, dispatch_queue_attr_t _Nullable attr);
 该函数的第一个参数指定Serial Dispatch Queue的名称。推荐使用应用程序ID这种逆序全程域名。
 
 第二个参数，当生成Serial Dispatch Queue（串行队列）时，第二个参数设置NULL。
 当生成Concurrent Dispatch Queue(并发队列)，指定为DISPATCH_QUEUE_CONCURRENT
 
 DISPATCH_QUEUE_SERIAL   表示串行队列，
 DISPATCH_QUEUE_CONCURRENT 表示并发队列。
 
 生成的Dispatch Queue必须由程序员负责释放
 
 构建任务分组
 dispatch_group_t dispatch_group_create(void);
 
 */

/*
 并发队列 + 异步任务
 并行的话很多任务会一起执行，要是异步任务的话会开启新的线程，那是不是我们添加了十个异步任务就会开启十条线程呢？那一百个异步任务岂不是要开启一百条线程，答案肯定是否定的！那系统到底是怎么处理的？
 当为 DISPATCH_QUEUE_CONCURRENT 的时候，不用等待前面任务的处理结束，后面的任务也是能够直接执行的
 并发执行的处理数量取决于当前系统的状态，即 iOS 和OS X基于Dispatch Queue中的处理数、CPU核数以及CPU负荷等当前系统状态来决定DISPATCH_QUEUE_CONCURRENT 中并行执行的处理数
 iOS 和 OS X的核心 -- XNU内核决定应当使用的线程数，并且生成所需的线程执行处理
 当处理结束，应当执行的处理数减少时，XNU内核会结束不在需要的线程
 处理并行异步任务时候线程是可以循环往复使用的，比如任务1的线程执行完了任务1，线程可以接着去执行后面没有执行的任务
 */
